#!/usr/bin/env python2
# -*- coding: utf-8 -*-


from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_sqlalchemy import BaseQuery
import config
from Ump.common import exception


class BaseFilterQuery(BaseQuery):
    def get(self, ident):
        # Override get() so that the flag is always checked in the
        # DB as opposed to pulling from the identity map. - this is optional.
        return BaseQuery.get(self.populate_existing(), ident)

    def __iter__(self):
        return BaseQuery.__iter__(self.private())

    def from_self(self, *ent):
        # Override from_self() to automatically apply
        # the criterion to.  this works with count() and
        # others.
        return BaseQuery.from_self(self.private(), *ent)

    def private(self):
        # Fetch the model name and column list and apply model-specific base filters
        mzero = self._mapper_zero()

        if mzero:
            # Sometimes a plain model class will be fetched instead of mzero
            try:
                model = mzero.class_
                obj = mzero.class_
            except Exception as e:
                model = mzero.__class__
                obj = mzero

            if getattr(model, 'is_check_deleted', None):
                model.is_check_deleted = 0
                return self
                
            if hasattr(model, '_base_filters'):
                return self.enable_assertions(False).filter(model._base_filters(obj))

        return self

db = SQLAlchemy(query_class=BaseFilterQuery, session_options={'query_cls': BaseFilterQuery})


def create_app(config_name, SQLALCHEMY_DATABASE_URI=None):

    app = Flask(__name__)
    flask_config_obj = config.DevelopmentConfig(SQLALCHEMY_DATABASE_URI=SQLALCHEMY_DATABASE_URI)

    app.config.from_object(flask_config_obj)

    db.init_app(app)

    from Ump.apps import (
        base,
        cluster,
        pdomain,
        host,
        token,
        user,
        disk,
        folder,
        qos,
        access_control,
        pool,
        volume,
        snapshot,
        vgroup,
        cgsnapshot,
        sysconfigforump,
        alert,
        remotecopy,
        db as _db,
        schedule,
        summary,
        pipe,
    )

    app.register_blueprint(token.app, url_prefix='/api/v1')
    app.register_blueprint(user.app, url_prefix='/api/v1')

    app.register_blueprint(cluster.app, url_prefix='/api/v1')
    app.register_blueprint(host.app, url_prefix='/api/v1')
    app.register_blueprint(disk.app, url_prefix='/api/v1')
    app.register_blueprint(pdomain.app, url_prefix='/api/v1')

    app.register_blueprint(folder.app, url_prefix='/api/v1')
    app.register_blueprint(qos.app, url_prefix='/api/v1')
    app.register_blueprint(access_control.app, url_prefix='/api/v1')
    app.register_blueprint(sysconfigforump.app, url_prefix='/api/v1')

    app.register_blueprint(pool.app, url_prefix='/api/v1')
    app.register_blueprint(volume.app, url_prefix='/api/v1')
    app.register_blueprint(snapshot.app, url_prefix='/api/v1')
    app.register_blueprint(vgroup.app, url_prefix='/api/v1')
    app.register_blueprint(cgsnapshot.app, url_prefix='/api/v1')
    app.register_blueprint(alert.app, url_prefix='/api/v1')
    app.register_blueprint(remotecopy.app, url_prefix='/api/v1')
    app.register_blueprint(_db.app, url_prefix='/api/v1')
    app.register_blueprint(schedule.app, url_prefix='/api/v1')
    app.register_blueprint(summary.app, url_prefix='/api/v1')
    app.register_blueprint(pipe.app, url_prefix='')

    return app, db
